package bancosys.tec.rtm.diagnostician;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * Classe abstrata para diagnostician nao precisarem lidar com excecoes
 * 
 * @author takeshi
 * @author Marcio Ribeiro (mmr)
 */
public abstract class AbstractDiagnostician implements Diagnostician {

    public static final String JMX_NAMESPACE = "jmine.tec.rtm";

    public static final int JMX_DEFAULT_CACHE_DURATION_IN_SECONDS = 5;

    private ExpiringCache<Map<String, Object>> valueCache = new ExpiringCache<Map<String, Object>>(JMX_DEFAULT_CACHE_DURATION_IN_SECONDS,
            new Callable<Map<String, Object>>() {

                public Map<String, Object> call() throws Exception {
                    return diagnosis().getValues();
                }
            });

    /**
     * {@inheritDoc}
     * 
     * @see bancosys.tec.rtm.diagnostician.Diagnostician#diagnosis()
     */
    public final DiagnosisBean diagnosis() {
        DiagnosisBean bean = new DiagnosisBean(this.getName());
        try {
            bean.setWorking(this.fillDiagnosisBean(bean));
        } catch (Throwable t) {
            bean.addDescription("exception thrown: " + t + " stack trace follows\n");
            final StringWriter stw = new StringWriter();
            PrintWriter writer = new PrintWriter(stw);
            t.printStackTrace(writer);
            bean.addDescription(stw.toString());
        }
        return bean;
    }

    /**
     * Devolve valor do mapa de valores com a chave passada.
     * 
     * @param key chave.
     * @return valor do mapa de valores com a chave passada.
     */
    protected Object getValue(String key) {
        return valueCache.get().get(key);
    }

    /**
     * Preenche o bean de diagnostico.
     * 
     * @param bean o bean do diagnostico.
     * @return <code>true</code> se executou com sucesso, <code>false</code> caso contrario.
     * @throws Exception em caso inesperado.
     */
    protected abstract boolean fillDiagnosisBean(DiagnosisBean bean) throws Exception;
}
